//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace OpenLS.UI
{
    ///<summary>
    /// Represents a UI Ribbon. 
    ///</summary>
    public class Ribbon : TabControl
    {


        public static FrameworkElement GetApplicationMenu(DependencyObject obj)
        {
            return (ApplicationMenu)obj.GetValue(ApplicationMenuProperty);
        }

        public static void SetApplicationMenu(DependencyObject obj, FrameworkElement value)
        {
            obj.SetValue(ApplicationMenuProperty, value);
        }

        // Using a DependencyProperty as the backing store for ApplicationMenu.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ApplicationMenuProperty =
            DependencyProperty.RegisterAttached("ApplicationMenu", typeof(FrameworkElement), typeof(Ribbon), new UIPropertyMetadata(null));

        
        
        public static readonly DependencyProperty StateProperty =
            DependencyProperty.Register("State", typeof (RibbonState), typeof (Ribbon),
                                        new UIPropertyMetadata(RibbonState.Expanded, onStateChangedThunk));

        private static void onStateChangedThunk(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ribbon = (Ribbon) d;
            ribbon.onStateChanged((RibbonState) e.OldValue, (RibbonState) e.NewValue);
        }

        private void onStateChanged(RibbonState oldValue, RibbonState newValue)
        {
            if (oldValue == newValue)
                return;
            if (newValue == RibbonState.Open)
                startTimer();
            if (oldValue == RibbonState.Open)
                stopTimer();
        }

        private bool _isMenuMode = false;
        private DispatcherTimer _mouseTimer;


        static Ribbon()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof (Ribbon),
                                                     new FrameworkPropertyMetadata(typeof (Ribbon)));
            FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof (Ribbon), new FrameworkPropertyMetadata(true));
            InputMethod.IsInputMethodSuspendedProperty.OverrideMetadata(typeof (Ribbon),
                                                                        new FrameworkPropertyMetadata(true,
                                                                                                      FrameworkPropertyMetadataOptions
                                                                                                          .Inherits));
            EventManager.RegisterClassHandler(typeof (Ribbon), Mouse.LostMouseCaptureEvent,
                                              new MouseEventHandler(onLostMouseCaptureThunk));
            EventManager.RegisterClassHandler(typeof (Ribbon), Mouse.PreviewMouseDownOutsideCapturedElementEvent,
                                              new MouseButtonEventHandler(onClickThroughThunk));
            EventManager.RegisterClassHandler(typeof (Ribbon), Mouse.PreviewMouseUpOutsideCapturedElementEvent,
                                              new MouseButtonEventHandler(onClickThroughThunk));
        }


        ///<summary>
        /// Get or set the state of the ribbon (Minimized, Open or Expanded), Expanded is the default
        ///</summary>
        public RibbonState State
        {
            get { return (RibbonState) GetValue(StateProperty); }
            set { SetValue(StateProperty, value); }
        }

         bool HasCapture
        {
            get { return (Mouse.Captured == this); }
        }



        bool isMenuMode
        {
            get { return _isMenuMode; }
            set
            {
                if (_isMenuMode == value)
                    return;
                _isMenuMode = value;
                bool flag = value;
                if (flag)
                {
                    if (!isDescendant(this, Mouse.Captured as Visual) && !Mouse.Capture(this, CaptureMode.SubTree))
                    {
                        //bool flag3 = false;
                        _isMenuMode = false;
                        flag = false;
                    }
                }
                if (!flag)
                {
                    if (HasCapture)
                    {
                        Mouse.Capture(null);
                    }
                }
            }
        }



        // Using a DependencyProperty as the backing store for IsOpen.  This enables animation, styling, binding, etc...
        private bool IgnoreNextRightRelease { get; set; }

        private static void onClickThroughThunk(object sender, MouseButtonEventArgs e)
        {
            ((Ribbon) sender).onClickThrough(e);
        }

        private void onClickThrough(MouseButtonEventArgs e)
        {
            if (((e.ChangedButton == MouseButton.Left) || (e.ChangedButton == MouseButton.Right)) && HasCapture)
            {
                bool flag = true;
                if (e.ButtonState == MouseButtonState.Released)
                {
                    if ((e.ChangedButton == MouseButton.Left) && false)
                    {
                        flag = false;
                    }
                    else if ((e.ChangedButton == MouseButton.Right) && IgnoreNextRightRelease)
                    {
                        IgnoreNextRightRelease = false;
                        flag = false;
                    }
                }
                if (flag)
                {
                    isMenuMode = false;
                }
            }
        }

        protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnIsKeyboardFocusWithinChanged(e);
            if (IsKeyboardFocusWithin)
            {
                if (!isMenuMode)
                {
                    isMenuMode = true;
                }
            }
            else
            {
                if (isMenuMode)
                {
                    if (HasCapture)
                    {
                        isMenuMode = false;
                    }
                }
            }
        }

        private static void onLostMouseCaptureThunk(object sender, MouseEventArgs e)
        {
            ((Ribbon)sender).onLostMouseCapture(sender, e);
        }

        private void onLostMouseCapture(object sender, MouseEventArgs e)
        {
            if (Mouse.Captured != this)
            {
                if (e.OriginalSource == this)
                {
                    if ((Mouse.Captured == null) || !isDescendant(this, Mouse.Captured as DependencyObject))
                    {
                        isMenuMode = false;
                    }
                }
                else if (isDescendant(this, e.OriginalSource as DependencyObject))
                {
                    if ((isMenuMode && (Mouse.Captured == null)) && true)
                        //\\ (SafeNativeMethods.GetCapture() == IntPtr.Zero))
                    {
                        Mouse.Capture(this, CaptureMode.SubTree);
                        e.Handled = true;
                    }
                }
                else
                {
                    isMenuMode = false;
                }
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

         void startTimer()
        {
             Contract.Assert(_mouseTimer == null);
            _mouseTimer = new DispatcherTimer(new TimeSpan(5000), DispatcherPriority.Background,
                                             onTimer, Dispatcher);
            _mouseTimer.Start();
        }
        void stopTimer
            ()
        {
            if (_mouseTimer == null)
                return;
            _mouseTimer.Stop();
            _mouseTimer = null;
        }

        private void onTimer(object sender, EventArgs e)
        {
            //return;
            //if (!IsOpen)
              //  return;
            if (State != RibbonState.Open)
                return;
            if (!isDescendant(this, Mouse.Captured as DependencyObject))
            {
                //IsOpen = false;
                State = RibbonState.Minimized;
            }
        }

        private static bool isDescendant(DependencyObject reference, DependencyObject node)
        {
            var o = node as FrameworkElement;
            while (o != null)
            {
                if (o == reference)
                {
                    return true;
                }
                if (o.Parent != null)
                    o = o.Parent as FrameworkElement;
                else if (o.TemplatedParent != null)
                    o = o.TemplatedParent as FrameworkElement;
                else
                    o = VisualTreeHelper.GetParent(o) as FrameworkElement;
            }
            return false;
        }

        internal void Open()
        {
            isMenuMode = true;
            //IsOpen = true;
            State = RibbonState.Open;
        }
    }
}